#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import cgi
import datetime
import wsgiref.handlers

from google.appengine.ext import db
from google.appengine.ext import webapp

from google.appengine.api.urlfetch import *

import logging
import feedparser

import xml.dom.minidom

class Opml(db.Model):
  opml_url = db.StringProperty()
  opml_output = db.TextProperty()

class Feed(db.Model):
  opml_url = db.StringProperty()
  feed_url = db.StringProperty()
  image_url = db.StringProperty()
  updated_at = db.DateTimeProperty(auto_now=True)

class PurgePage(webapp.RequestHandler):
  def get(self):
    opml_url = self.request.get('url')
    counter = 0
    #for opml_feed in Feed.gql("WHERE opml_url = :1", opml_url):
    for opml_feed in Feed.gql(""):
      Feed.delete (opml_feed)
      counter += 1
    self.response.out.write ("Deleted " + str(counter) + " items")

class MainPage(webapp.RequestHandler):
  def get(self):
    opml_url = self.request.get('url')
    self.response.headers['Content-Type'] = 'text/xml'

    q = Feed.gql("WHERE opml_url = :1", opml_url)
    opml = q.get()
    if opml != None:
      self.response.out.write(opml.opml_output)
      return
        
    # Grab the OPML file
    opml_dom = xml.dom.minidom.parseString(fetch(opml_url).content)

    opml_feed_dict = {}
    for opml_feed in Feed.gql("WHERE opml_url = :1", opml_url):
      opml_feed_dict[opml_feed.feed_url] = opml_feed

    # Parse its contents
    counter = 0
    
    for outline_element in opml_dom.getElementsByTagName ('outline'):
      if outline_element.hasAttribute('xmlUrl'):
        feed_obj = None
        feed_url = outline_element.getAttribute('xmlUrl')

        if not opml_feed_dict.has_key(feed_url):
          try:
            logging.debug("getting feed " + str(counter))
            counter += 1
            result = fetch(feed_url)
            if result.status_code != 200:
              self.response.out.write('did not get 200')
              continue
          
            rss = feedparser.parse(result.content)

            feed_obj = Feed(feed_url = feed_url, image_url = rss.feed.image.href, opml_url=opml_url)
            feed_obj.put()

            opml_feed_dict[feed_url] = feed_obj
          except:
            logging.debug("failed to get feed " + feed_url)
            continue
        else:
          feed_obj = opml_feed_dict[feed_url]
          logging.debug("got cached feed " + feed_url)

        outline_element.setAttribute ('imageUrl', feed_obj.image_url)

    opml_output = opml_dom.toxml()

    opml_obj = Opml(opml_url=opml_url, opml_output=opml_output)
    opml_obj.put()

    self.response.out.write (opml_output)

  def handle_exception(exception, debug_mode):
    logging.debug("got exception " + str(exception))

application = webapp.WSGIApplication([
  ('/process', MainPage),
  ('/purge', PurgePage)
], debug=True)


def main():
  wsgiref.handlers.CGIHandler().run(application)


if __name__ == '__main__':
  main()
